import socket
import threading
import struct

# 你的用户名和密码
USERNAME = 'root'
PASSWORD = 'za111456'

def handle_client_connection(client_socket):

    version, nmethods = client_socket.recv(2)

    methods = client_socket.recv(nmethods)

    if 2 not in methods:
        client_socket.close()
        return
    client_socket.sendall(b'\x05\x02')  


    version = client_socket.recv(1)
    ulen = client_socket.recv(1)
    username = client_socket.recv(ord(ulen))
    plen = client_socket.recv(1)
    password = client_socket.recv(ord(plen))
    if username.decode() == USERNAME and password.decode() == PASSWORD:
        client_socket.sendall(b'\x01\x00')  
    else:
        client_ip = client_socket.getpeername()[0]
        print(f"用户名与密码验证失败，来自IP地址：{client_ip}")
        client_socket.sendall(b'\x01\x01') 
        client_socket.close()
        return


    version, cmd, _, address_type = client_socket.recv(4)
    if cmd != 1: 
        client_socket.close()
        return


    if address_type == 1:  
        address = socket.inet_ntoa(client_socket.recv(4))
    elif address_type == 3:  
        domain_length = client_socket.recv(1)[0]
        address = client_socket.recv(domain_length)
    elif address_type == 4:  
        address = socket.inet_ntop(socket.AF_INET6, client_socket.recv(16))
    else:
        client_socket.close()
        return
    port = int.from_bytes(client_socket.recv(2), 'big')


    remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    remote_socket.connect((address, port))

    client_socket.sendall(b'\x05\x00\x00\x01' + socket.inet_aton('0.0.0.0') + (1011).to_bytes(2, 'big'))

    def relay(src, dst):
        try:
            while True:
                data = src.recv(4096)
                if not data:
                    break
                dst.sendall(data)
        except ConnectionResetError:
            pass

    client_to_remote = threading.Thread(target=relay, args=(client_socket, remote_socket))
    remote_to_client = threading.Thread(target=relay, args=(remote_socket, client_socket))

    client_to_remote.start()
    remote_to_client.start()

    client_to_remote.join()
    remote_to_client.join()

    client_socket.close()
    remote_socket.close()

def main():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(('0.0.0.0', 1011))
    server_socket.listen(5)

    print("Socks5代理已运行在1011端口...")

    try:
        while True:
            client_socket, _ = server_socket.accept()
            client_thread = threading.Thread(target=handle_client_connection, args=(client_socket,))
            client_thread.start()
    finally:
        server_socket.close()

if __name__ == '__main__':
    main()
